                .586
                .MMX
				;.XMM
                TITLE   FILTER
                .MODEL  FLAT, STDCALL

INTEL_P_Filter__NO_SSE	PROTO	C, Buf:DWORD, W:DWORD, H:DWORD, CenterScale:DWORD
INTEL_Extrem_Filter_MinMax__NO_SSE	PROTO	C, Buf:DWORD, W:DWORD, H:DWORD
INTEL_Extrem_Filter_Aver__NO_SSE	PROTO	C, Buf:DWORD, W:DWORD, H:DWORD, Max_Min:DWORD


;====================================================================
;				                                                    
;				SSE - EMULATOR																
;																	
;====================================================================

PCMPAboveB	MACRO	RMM1, RMM2
		MOVQ	mem1,RMM1
		MOVQ	mem2,RMM2

		PSUBUSB	RMM2,RMM1
		PXOR	RMM1,RMM1
		PCMPEQB	RMM1,RMM2	

ENDM



_PMINUB	MACRO	RMM1, RMM2


		PCMPAboveB	RMM1, RMM2
		
		MOVQ	RMM2,mem1
		POR		RMM2,RMM1
		PXOR	RMM2,RMM1
		PAND	RMM1,mem2
		POR		RMM1,RMM2
		MOVQ	RMM2,mem2

ENDM


_PMAXUB	MACRO	RMM1, RMM2
		
		PCMPAboveB	RMM1, RMM2

		MOVQ	RMM2,mem2
		POR		RMM2,RMM1
		PXOR	RMM2,RMM1
		PAND	RMM1,mem1
		POR		RMM1,RMM2
		MOVQ	RMM2,mem2

ENDM


_PAVGB	MACRO	RMM1, RMM2
		MOVQ	mem1,RMM1
		MOVQ	mem2,RMM2


		PSRLQ	RMM1,1
		PSRLQ	RMM2,1

		PAND	RMM1,QWORD PTR [Bs7F]
		PAND	RMM2,QWORD PTR [Bs7F]
		
		PADDB	RMM1,RMM2

		MOVQ	RMM2,mem1
		MOVQ	mem1,RMM1
		MOVQ	RMM1,mem2
		PAND	RMM1,QWORD PTR [Bs01]
		PAND	RMM2,QWORD PTR [Bs01]
		PADDB	RMM1,RMM2
		PADDB	RMM1,QWORD PTR [Bs01]
		MOVQ	RMM2,mem1
		PSRLQ	RMM1,1
		PAND	RMM1,QWORD PTR [Bs01]
		PADDB	RMM1,RMM2
		MOVQ	RMM2,mem2
ENDM



;====================================================================
;				                                                    
;				M A C R O																
;																	
;====================================================================

RepeatPADDW	MACRO	Dest, Sorc, CenterRep

		Shift = 0
IRPC	Msk, <1248>
IF		(CenterRep and Msk)
IF		(Shift)
		PSLLW	Sorc,Shift
		Shift = 0
ENDIF
		PADDW	Dest,Sorc
ENDIF
		Shift = Shift+1
ENDM
ENDM						

P_Filter8	MACRO	Dest, Top, Center, Bottom, CenterRep

		MOVQ	MM0,[Center-1]
		PXOR	MM7,MM7

		;MOVD	MM3,[Top]	;This instruction got a syntax error with MASM9.0 (VS2008)
							;then replace the following code. (FIXED BY KAZUHY:#VS2008)
		PUSH	EAX			; 
		MOV		EAX,[Top]	;
		MOVD	MM3,EAX		;
		POP		EAX			;

		MOVQ	MM1,MM0
		MOVQ	MM4,[Bottom]
		PSRLQ	MM1,8

		MOVQ	MM2,MM0		
		PUNPCKLBW	MM0,MM7

		PSRLQ	MM2,16
		PUNPCKLBW	MM1,MM7

		;;PADDW	MM0,MM1
		RepeatPADDW	MM0, MM1, CenterRep 

		PUNPCKLBW	MM2,MM7

		PADDW	MM0,MM2
		PUNPCKLBW	MM3,MM7

		PADDW	MM0,MM3
		PUNPCKLBW	MM4,MM7
		
		MOVQ	MM1,[Center+4-1]
		PADDW	MM0,MM4
		
		MOVQ	MM2,[Top+4]
		PMULHW	MM0,MM6

		MOVQ	MM3,[Bottom+4]
		MOVQ	MM4,MM1
		

		PSRLQ	MM4,8
		MOVQ	MM5,MM1	
		
		PSRLQ	MM5,16

		PUNPCKLBW	MM1,MM7
		PUNPCKLBW	MM2,MM7
		PADDW	MM1,MM2
		PUNPCKLBW	MM3,MM7
		PADDW	MM1,MM3
		PUNPCKLBW	MM4,MM7
		
		;;PADDW	MM1,MM4
		RepeatPADDW	MM1, MM4, CenterRep 

		
		PUNPCKLBW	MM5,MM7
		PADDW	MM1,MM5


		PMULHW	MM1,MM6
			

		PACKUSWB	MM0,MM1
		MOVQ	[Dest],MM0
ENDM


CopyLine	MACRO	Dest
LOCAL	L				
		LEA		ECX,[EBX+7]
		SHR		ECX,3
		MOV		EAX,0

L:		MOVQ	MM0,[EDX+EAX]
		MOVQ	[Dest+EAX],MM0
		ADD		EAX,8
		LOOP	L

		MOV		AL,[Dest]
		MOV		[Dest-1],AL

		MOV		AL,[Dest+EBX-1]
		MOV		[Dest+EBX],AL
ENDM

CopyLine1	MACRO	Dest
LOCAL	L				
		LEA		ECX,[EBX+7]
		SHR		ECX,3
		MOV		EAX,0

L:		MOVQ	MM0,[EDX+EAX]
		MOVQ	[Dest+EAX],MM0
		ADD		EAX,8
		LOOP	L

ENDM


Extr_Filter_MinMax	MACRO	Dest, Top, Center, Bottom
		MOVQ	MM0,[Top]
		MOVQ	MM1,[Bottom]
		MOVQ	MM2,MM0
		_PMINUB	MM0,MM1
		_PMAXUB	MM1,MM2
		
		MOVQ	MM2,[Top+1]
		MOVQ	MM3,[Bottom+1]
		MOVQ	MM4,MM2
		_PMINUB	MM2,MM3
		_PMAXUB	MM3,MM4

		_PMINUB	MM0,MM2
		_PMAXUB	MM1,MM3

		MOVQ	MM2,[Top+2]
		MOVQ	MM3,[Bottom+2]
		MOVQ	MM4,MM2
		_PMINUB	MM2,MM3
		_PMAXUB	MM3,MM4

		MOVQ	MM4,[Center]
		MOVQ	MM5,[Center+2]
		MOVQ	MM6,MM4
		_PMINUB	MM4,MM5
		_PMAXUB	MM5,MM6

		_PMINUB	MM2,MM4
		_PMAXUB	MM3,MM5

		MOVQ	MM4,[Center+1]
		_PMINUB	MM0,MM2				;; MIN ready 
		_PMAXUB	MM1,MM3				;; MAX ready

		
		_PMINUB	MM4,MM1				;; if (buf[x]>Max[0]) buf[x]=Max[0] 
		_PMAXUB	MM4,MM0				;; if (buf[x]<Min[0]) buf[x]=Min[0]

		MOVQ	[Dest+1],MM4
ENDM



Extr_Filter_Aver	MACRO	Dest, Top, Center, Bottom
		MOVQ	MM0,[Top]
		MOVQ	MM1,[Bottom]
		MOVQ	MM2,MM0
		_PMINUB	MM0,MM1
		_PMAXUB	MM1,MM2
		
		MOVQ	MM2,[Top+1]
		MOVQ	MM3,[Bottom+1]
		MOVQ	MM4,MM2
		_PMINUB	MM2,MM3
		_PMAXUB	MM3,MM4

		_PMINUB	MM0,MM2
		_PMAXUB	MM1,MM3

		MOVQ	MM2,[Top+2]
		MOVQ	MM3,[Bottom+2]
		MOVQ	MM4,MM2
		_PMINUB	MM2,MM3
		_PMAXUB	MM3,MM4

		MOVQ	MM4,[Center]
		MOVQ	MM5,[Center+2]
		MOVQ	MM6,MM4
		_PMINUB	MM4,MM5
		_PMAXUB	MM5,MM6

		_PMINUB	MM2,MM4
		_PMAXUB	MM3,MM5

		MOVQ	MM4,[Center+1]
		_PMINUB	MM0,MM2				;; MIN ready 
		MOVQ	MM2,[Center]
		_PMAXUB	MM1,MM3				;; MAX ready
		MOVQ	MM3,[Top+1]

		MOVQ	MM5,[Center+2]
		MOVQ	MM6,[Bottom+1]
		_PAVGB	MM2,MM5
		_PAVGB	MM3,MM6	
		_PAVGB	MM2,MM3				;; Aver ready

		MOVQ	MM5,MM1
		MOVQ	MM3,MM7
		PSUBB	MM5,MM0
		PXOR	MM6,MM6
		PSUBUSB	MM3,MM5
		PCMPEQB	MM3,MM6				;; if ((Max[0]-Min[0])>=Max_Min) then FF else 00 
		MOVQ	MM5,MM4

		MOVQ	MM6,MM2
		POR		MM2,MM3
		_PAVGB	MM6,MM4				;; (Aver + buf[x] + 1)>>1
		PXOR	MM2,MM3
		PAND	MM6,MM3
		POR		MM2,MM6				;; Aver  OR  (Aver + buf[x] + 1)>>1

		PSUBUSB	MM1,MM4
		PXOR	MM6,MM6
		PSUBUSB	MM4,MM0
		PCMPEQB	MM1,MM6				;; if (buf[x]>=Max[0]) then FF
		PCMPEQB	MM4,MM6				;; if (buf[x]<=Min[0]) then FF
		POR		MM1,MM4
		
		POR		MM5,MM1
		PAND	MM2,MM1
		PXOR	MM5,MM1
		POR		MM5,MM2 


		MOVQ	[Dest+1],MM5
ENDM



;====================================================================
;
;				D A T A
;
;====================================================================
				.DATA
				ALIGN	8

KKKK	LABEL	QWORD
		CSc = -1
REPT	16
		CSc = CSc+1
		DW		4 DUP (10000h/(4+CSc))
ENDM
Bs01			DB		8 DUP (01h)		
Bs7F			DB		8 DUP (7Fh)		

;====================================================================
;
;				C O D E
;
;====================================================================
				.CODE

;___________________________________________________________________________________________________________________________
;
;				INTEL_P_Filter
;___________________________________________________________________________________________________________________________
INTEL_P_Filter__NO_SSE	PROC	C, Buf:DWORD, W:DWORD, H:DWORD, CenterScale:DWORD
		PUSHAD


;________________LOCAL VARIABLES__________________________________________________________
		MOV		EAX,[W]
		LEA		EAX,[EAX*2+16*2+4+8]
		SUB		ESP,EAX										; WARNING!!!!!!! 
				Save8			EQU QWORD PTR [ESP]			; 
				SaveEDX			EQU DWORD PTR [ESP+8]		; DONT USE PUSH-POP-CALL
;_____________________________________________________________________________________
		
		LEA		ESI,[ESP+12+8]
		AND		ESI,not 7		
		LEA		EDI,[ESI+2+8]
		ADD		EDI,[W]
		AND		EDI,not 7		
		INC		ESI
		INC		EDI			


		CScale = -1
REPT	16
LOCAL	Continue, L5, L10, L20 
		CScale = CScale + 1

		CMP		[CenterScale],CScale
		JNE		Continue

		MOVQ	MM6,QWORD PTR [KKKK+CScale*8]

		MOV		EBX,[W]

		DEC		[H]


		MOV		EDX,[Buf]

		CopyLine ESI

L5:		CopyLine EDI
		
		
		LEA		ECX,[EBX+7]
		SHR		ECX,3
		MOV		EAX,0

		MOV		[SaveEDX],EDX
		MOVQ	MM0,[EDX+EBX]
		MOVQ	[Save8],MM0

		
L10:
		P_Filter8	EDX, ESI+EAX, EDI+EAX, EDX+EBX, CScale 
						
		ADD		EAX,8
		ADD		EDX,8
		DEC		ECX
		JNE		L10

		MOV		EDX,[SaveEDX]

		MOVQ	MM0,[Save8]
		MOVQ	[EDX+EBX],MM0

		XCHG	ESI,EDI
		ADD		EDX,EBX
		DEC		[H]
		JNE		L5


		CopyLine EDI
		
		
		LEA		ECX,[EBX+7]
		SHR		ECX,3
		MOV		EAX,0
		MOV		[SaveEDX],EDX
		MOVQ	MM0,[EDX+EBX]
		MOVQ	[Save8],MM0
		
L20:
		P_Filter8	EDX, ESI+EAX, EDI+EAX, EDI+EAX, CScale 
						
		ADD		EAX,8
		ADD		EDX,8
		DEC		ECX
		JNE		L20

		MOV		EDX,[SaveEDX]
		MOVQ	MM0,[Save8]
		MOVQ	[EDX+EBX],MM0


		JMP		@@100
Continue:
ENDM

@@100:

		
		MOV		EAX,[W]
		LEA		EAX,[EAX*2+16*2+4+8]
		ADD		ESP,EAX										
		POPAD
		EMMS

		RET		

INTEL_P_Filter__NO_SSE	ENDP


;___________________________________________________________________________________________________________________________
;
;				INTEL_Extrem_Filter_MinMax__NO_SSE
;___________________________________________________________________________________________________________________________
INTEL_Extrem_Filter_MinMax__NO_SSE	PROC	C, Buf:DWORD, W:DWORD, H:DWORD
		PUSHAD




;________________LOCAL VARIABLES__________________________________________________________
		MOV		EAX,[W]
		LEA		EAX,[EAX*2+16*2+4+8*3]
		SUB		ESP,EAX										; WARNING!!!!!!! 
				Save8			EQU QWORD PTR [ESP]			; 
				mem1 			EQU	QWORD PTR [ESP+8]
				mem2 			EQU	QWORD PTR [ESP+16]
				SaveEDX			EQU DWORD PTR [ESP+24]		; DONT USE PUSH-POP-CALL

;_____________________________________________________________________________________
		
		LEA		ESI,[ESP+4+8*3+8]
		AND		ESI,not 7		
		LEA		EDI,[ESI+2+8]
		ADD		EDI,[W]
		AND		EDI,not 7		


		MOV		EBX,[W]

		DEC		[H]


		MOV		EDX,[Buf]

		CopyLine1 ESI

@@5:	CopyLine1 EDI
		
		
		LEA		ECX,[EBX+7-2]
		SHR		ECX,3
		MOV		EAX,0

		MOV		[SaveEDX],EDX
		MOVQ	MM0,[EDX+EBX-1]
		MOVQ	[Save8],MM0

		
@@10:
		Extr_Filter_MinMax	EDX, ESI+EAX, EDI+EAX, EDX+EBX 
						
		ADD		EAX,8
		ADD		EDX,8
		DEC		ECX
		JNE		@@10

		MOV		EDX,[SaveEDX]

		MOVQ	MM0,[Save8]
		MOVQ	[EDX+EBX-1],MM0

		XCHG	ESI,EDI
		ADD		EDX,EBX
		DEC		[H]
		JNE		@@5


		CopyLine1 EDI
		
		
		LEA		ECX,[EBX+7-2]
		SHR		ECX,3
		MOV		EAX,0
		MOV		[SaveEDX],EDX
		MOVQ	MM0,[EDX+EBX-1]
		MOVQ	[Save8],MM0
		
@@20:
		Extr_Filter_MinMax	EDX, ESI+EAX, EDI+EAX, EDI+EAX 
						
		ADD		EAX,8
		ADD		EDX,8
		DEC		ECX
		JNE		@@20

		MOV		EDX,[SaveEDX]
		MOVQ	MM0,[Save8]
		MOVQ	[EDX+EBX-1],MM0

		
		MOV		EAX,[W]
		LEA		EAX,[EAX*2+16*2+4+8*3]
		ADD		ESP,EAX										
		POPAD
		EMMS

		RET		

INTEL_Extrem_Filter_MinMax__NO_SSE	ENDP


;___________________________________________________________________________________________________________________________
;
;				INTEL_Extrem_Filter_Aver__NO_SSE
;___________________________________________________________________________________________________________________________
INTEL_Extrem_Filter_Aver__NO_SSE	PROC	C, Buf:DWORD, W:DWORD, H:DWORD, Max_Min:DWORD
		PUSHAD




;________________LOCAL VARIABLES__________________________________________________________
		MOV		EAX,[W]
				Len = 4+8+8+8+8
		LEA		EAX,[EAX*2+16*2+Len]
		SUB		ESP,EAX										; WARNING!!!!!!! 
				Save8			EQU QWORD PTR [ESP]			; 
				mem1 			EQU	QWORD PTR [ESP+8]
				mem2 			EQU	QWORD PTR [ESP+16]
				Max_Min8		EQU QWORD PTR [ESP+24]
				SaveEDX			EQU DWORD PTR [ESP+32]		; DONT USE PUSH-POP-CALL
;_____________________________________________________________________________________
		
		LEA		ESI,[ESP+Len+8]
		AND		ESI,not 7		
		LEA		EDI,[ESI+2+8]
		ADD		EDI,[W]
		AND		EDI,not 7		


		MOV		EBX,[W]


		DEC		[H]


		MOV		EDX,[Buf]


		MOV		EAX,[Max_Min]
		MOV		AH,AL
		MOV		ECX,EAX
		SHL		EAX,16
		MOV		AX,CX
		MOVD	MM7,EAX
		PUNPCKLDQ MM7,MM7				;; 8 DUP (Max_Min)



		CopyLine1 ESI

@@5:	CopyLine1 EDI
		
		
		LEA		ECX,[EBX+7-2]
		SHR		ECX,3
		MOV		EAX,0

		MOV		[SaveEDX],EDX
		MOVQ	MM0,[EDX+EBX-1]
		MOVQ	[Save8],MM0

		
@@10:
		Extr_Filter_Aver	EDX, ESI+EAX, EDI+EAX, EDX+EBX 
						
		ADD		EAX,8
		ADD		EDX,8
		DEC		ECX
		JNE		@@10

		MOV		EDX,[SaveEDX]

		MOVQ	MM0,[Save8]
		MOVQ	[EDX+EBX-1],MM0

		XCHG	ESI,EDI
		ADD		EDX,EBX
		DEC		[H]
		JNE		@@5


		CopyLine1 EDI
		
		
		LEA		ECX,[EBX+7-2]
		SHR		ECX,3
		MOV		EAX,0
		MOV		[SaveEDX],EDX
		MOVQ	MM0,[EDX+EBX-1]
		MOVQ	[Save8],MM0
		
@@20:
		Extr_Filter_Aver	EDX, ESI+EAX, EDI+EAX, EDI+EAX 
						
		ADD		EAX,8
		ADD		EDX,8
		DEC		ECX
		JNE		@@20

		MOV		EDX,[SaveEDX]
		MOVQ	MM0,[Save8]
		MOVQ	[EDX+EBX-1],MM0

		
		MOV		EAX,[W]
		LEA		EAX,[EAX*2+16*2+Len]
		ADD		ESP,EAX										
		POPAD
		EMMS

		RET		

INTEL_Extrem_Filter_Aver__NO_SSE	ENDP



END
